package com.qf.service.impl;

import com.qf.cache.CategoryCache;
import com.qf.entity.SysCategory;
import com.qf.entity.SysCategoryExample;
import com.qf.entity.SysUserInfo;
import com.qf.events.CategoryChangeEvent;
import com.qf.exceptions.AddDataException;
import com.qf.exceptions.DeleteDataException;
import com.qf.exceptions.QueryDataException;
import com.qf.exceptions.ResultCode;
import com.qf.mapper.SysCategoryDao;
import com.qf.mapper.SysCategoryMapper;
import com.qf.pojo.BaseUser;
import com.qf.pojo.CheckType;
import com.qf.service.CategoryService;
import com.qf.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author ztf
 * @Date 17:44 2021/12/29
 **/
@Service
@Transactional(rollbackFor = RuntimeException.class)
public class CategoryServiceImpl implements CategoryService {

    private CategoryCache categoryCache;

    private SysCategoryDao sysCategoryDao;

    private SysCategoryMapper sysCategoryMapper;

    private ApplicationContext context;

    @Autowired
    public void setCategoryCache(CategoryCache categoryCache) {
        this.categoryCache = categoryCache;
    }

    @Autowired
    public void setSysCategoryDao(SysCategoryDao sysCategoryDao) {
        this.sysCategoryDao = sysCategoryDao;
    }

    @Autowired
    public void setSysCategoryMapper(SysCategoryMapper sysCategoryMapper) {
        this.sysCategoryMapper = sysCategoryMapper;
    }

    @Autowired
    public void setContext(ApplicationContext context) {
        this.context = context;
    }

    @Override
    public List<SysCategory> findAllCategory() {
        List<SysCategory> allData = categoryCache.getAllData();
        return allData;
    }

    @Override
    public SysCategory findCategoryById(Integer id) {
        //非空判断
        Assert.isTrue(id > 0, () -> {
            throw new QueryDataException("CategoryServiceImpl:findCategoryById id 为空", ResultCode.ID_NULL);
        });

        SysCategory category = categoryCache.getValue(id);
        return category;
    }

    @Override
    public List<SysCategory> findCategoryByName(String cname) {

        //非空判断
        Assert.hasText(cname, () -> {
            throw new QueryDataException("CategoryServiceImpl:findCategoryByName id name 为空", ResultCode.CATEGORY_NAME_NULL);
        });
        //获取所有分类
        List<SysCategory> allData = categoryCache.getAllData();
        //根据分类名获取分类
        List<SysCategory> categoryList = allData.stream()
                .filter(sysCategory ->
                        sysCategory.getCategoryName()
                                .contains(cname))
                .collect(Collectors.toList());

        return categoryList;
    }

    @Override
    public Integer deleteCategoryByIds(List<Integer> ids) {
        //非空判断
        Assert.notEmpty(ids, () -> {
            throw new DeleteDataException("CategoryServiceImpl：deleteCategoryByIds id为空", ResultCode.ID_NULL);
        });
        Integer result = sysCategoryMapper.deleteById(ids);

        //发布事件
        context.publishEvent(new CategoryChangeEvent());

        return result;
    }

    @Override
    public void addCategory(SysCategory sysCategory) {
        //检查参数是否完整
        Assert.isTrue(!sysCategory.isEmpty(CheckType.ADD), () -> {
            throw new AddDataException("CategoryServiceImpl:addCategory 必传参数不完整，请检查", ResultCode.USERNAME_NULL);
        });

        //检查分类是否已存在
        SysCategoryExample sysCategoryExample = new SysCategoryExample();
        SysCategoryExample.Criteria sysCategoryExampleCriteria = sysCategoryExample.createCriteria();
        sysCategoryExampleCriteria.andCategoryNameEqualTo(sysCategory.getCategoryName());

        List<SysCategory> categoryList = sysCategoryDao.selectByExample(sysCategoryExample);
        Assert.notNull(categoryList, () -> {
            throw new AddDataException("CategoryServiceImpl:addCategory 该分类名已存在", ResultCode.CATEGORY_NAME_REPEAT);
        });

        //设置添加时间
        sysCategory.setCreateTime(new Date());

        //获取当前添加分类的用户
        BaseUser user = SecurityUtils.getUser();
        sysCategory.setCreateBy(user.getUsername());

        //将分类添加到数据库
        sysCategoryDao.insert(sysCategory);

        //发送一个事件
        context.publishEvent(new CategoryChangeEvent());

    }
}
